const jwt = require("jsonwebtoken");
const { NAME_OR_PASSWORD_IS_REQUIRED, NAME_IS_NOT_EXIST, PASSWORD_IS_INCORRECT } = require("../config/error-constants");
const userService = require("../service/user.service");
const { md5Password } = require("../utils");
const { PUBLIC_KEY } = require("../config/secret");
const { UNAUTHORIZATION } = require("../config/error-constants");

const verifyLoginParams = async (ctx, next) => {
    // 1.获取登录名和密码，检测参数个数
    const { name, password } = ctx.request.body;
    if (!name || !password) {
        return ctx.app.emit("error", NAME_OR_PASSWORD_IS_REQUIRED, ctx);
    }
    // 2.查询数据库是否有这样的用户
    const users = await userService.findUserByName(name);
    const user = users[0];
    if (!user) {
        return ctx.app.emit("error", NAME_IS_NOT_EXIST, ctx);
    }
    // 3.判断数据库查到的用户密码与参数密码是否一致
    const { password: pwd } = user;
    if (pwd !== md5Password(password)) {
        return ctx.app.emit("error", PASSWORD_IS_INCORRECT, ctx);
    }

    // 4.将user对象保存到ctx中，以便下一个中间件(login.controller)能够拿到user对象
    ctx.user = user;
    await next();
};

/**
 * @description 验证token中间件
 * @param {*} ctx
 * @param {*} next
 */
const verifyAuthorization = async (ctx, next) => {
    // 1.获取token
    const authorization = ctx.headers.authorization;
    if (!authorization) {
        return ctx.app.emit("error", UNAUTHORIZATION, ctx);
    }
    const token = authorization.replace("Bearer ", "");
    // 2.验证token
    try {
        // 2.1. 获取token信息
        const result = jwt.verify(token, PUBLIC_KEY, {
            algorithms: ["RS256"],
        });

        // 2.2. 将token信息保存下来
        ctx.user = result;

        // 2.3. 执行下一个中间件
        await next();
    } catch (error) {
        console.log(error);
        ctx.app.emit("error", UNAUTHORIZATION, ctx);
    }
};

module.exports = {
    verifyLoginParams,
    verifyAuthorization,
};
